package com.zhouzhou.fastjava.excel;

import com.zhouzhou.fastjava.excel.exception.InvalidFormatExcelException;
import com.zhouzhou.fastjava.excel.exception.UnreadableExcelException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import com.zhouzhou.fastjava.excel.exception.ImportException;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.function.Consumer;

public abstract class ExcelUtils {

    public static Map<Integer, String[]> readRows(File file, int colNum) throws InvalidFormatException, IOException {
        try (InputStream is = new FileInputStream(file)) {
            return ExcelReader.readRows(WorkbookFactory.create(is), colNum);
        }
    }

    public static Map<Integer, String[]> readWithChecking(String originFilename, InputStream is, ColumnQualifier[] columnQualifiers) throws UnreadableExcelException, InvalidFormatExcelException, ImportException {
        return ExcelReader.readWithChecking(originFilename, is, columnQualifiers, r -> {
        });
    }

    public static void checkingAndConsume(String originFilename, InputStream is, ColumnQualifier[] columnQualifiers, Consumer<String[]> consumer) throws UnreadableExcelException, InvalidFormatExcelException, ImportException {
        ExcelReader.readWithChecking(originFilename, is, columnQualifiers, consumer);
    }

    public static void copyRow(Workbook workbook, Sheet sheet, int sourceRowNum, int destinationRowNum) {

        Row newRow = sheet.getRow(destinationRowNum);
        Row sourceRow = sheet.getRow(sourceRowNum);
        if (newRow != null) {
            sheet.shiftRows(destinationRowNum, sheet.getLastRowNum(), 1);
        } else {
            newRow = sheet.createRow(destinationRowNum);
        }
        // Loop through source columns to add to new row
        for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
            // Grab a copy of the old/new cell
            Cell oldCell = sourceRow.getCell(i);
            Cell newCell = newRow.createCell(i);

            // If the old cell is null jump to next cell
            if (oldCell == null) {
                newCell = null;
                continue;
            }

            // Copy style from old cell and apply to new cell
            CellStyle newCellStyle = workbook.createCellStyle();
            newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
            newCell.setCellStyle(newCellStyle);

            // If there is a cell comment, copy
            if (oldCell.getCellComment() != null) {
                newCell.setCellComment(oldCell.getCellComment());
            }

            // If there is a cell hyperlink, copy
            if (oldCell.getHyperlink() != null) {
                newCell.setHyperlink(oldCell.getHyperlink());
            }

            // Set the cell data type
            newCell.setCellType(oldCell.getCellType());

            // Set the cell data value
            switch (oldCell.getCellType()) {
                case Cell.CELL_TYPE_BLANK:
                    newCell.setCellValue(oldCell.getStringCellValue());
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    newCell.setCellValue(oldCell.getBooleanCellValue());
                    break;
                case Cell.CELL_TYPE_ERROR:
                    newCell.setCellErrorValue(oldCell.getErrorCellValue());
                    break;
                case Cell.CELL_TYPE_FORMULA:
                    newCell.setCellFormula(oldCell.getCellFormula());
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    newCell.setCellValue(oldCell.getNumericCellValue());
                    break;
                case Cell.CELL_TYPE_STRING:
                    newCell.setCellValue(oldCell.getRichStringCellValue());
                    break;
            }
        }
        // If there are are any merged regions in the source row, copy to new
        // row
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress cellRangeAddress = sheet.getMergedRegion(i);
            if (cellRangeAddress.getFirstRow() == sourceRow.getRowNum()) {
                CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.getRowNum(),
                        (newRow.getRowNum() + (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())),
                        cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn());
                sheet.addMergedRegion(newCellRangeAddress);
            }
        }
    }

    private ExcelUtils() {
    }

}
